import { ThreeTDSLoader } from '../infrastructure/three-render/loader/ThreeTDSLoader'
import { RoomZIPLoader } from '../infrastructure/resource-management/RoomZIPLoader'
import { MeshBuilderManager } from '../infrastructure/three-render/build/MeshBuilderManager'
import { ThreeMaterialManager } from '../infrastructure/three-render/ThreeMaterialManager'
import { ThreeRender3DController } from '../infrastructure/three-render/ThreeRender3DController'
import { ThreeSceneController } from '../infrastructure/three-render/ThreeSceneController'
import { ThreeTextureManager } from '../infrastructure/three-render/ThreeTextureManager'
import { DomainServiceContainer } from './container/DomainServiceContainer'
import { ThreeModelResourceManager } from '../infrastructure/three-render/ThreeModelResourceManager'
import { ThreeGLTFLoader } from '../infrastructure/three-render/loader/ThreeGLTFLoader'

/**
 * 一个全局容器，用来模拟ioc容器，主要目的是为了以后实现《依赖倒置》
 * 1、这里需要实例化所有需要用到的持久层infrastructure实体
 * 2、doServiceContainer 存储领域Service实体
 * 说明：这里让上层实体不直接new下层实体，而是去GlobalContainer拿，
 * 后续有需要，可通过依赖继承或接口实现替换，只需要改这里new的实体即可
 *
 * 注意：这里需要注意下层实体必须先实例化，
 * 改进思路：不在这里手动new，而是存储实体的构造函数，程序执行过程中用到的时候自然会调用去实例化
 */
export class GlobalContainer {
  /** 存储各种领域Service实体 */
  public static doServiceContainer: DomainServiceContainer

  /**存储基础层的相关控制器 */

  //#region three-render three渲染
  public static threeSceneController: ThreeSceneController
  public static threeRender3DController: ThreeRender3DController
  public static meshBuilderManager: MeshBuilderManager
  public static threeTextureManager: ThreeTextureManager
  public static threeMaterialManager: ThreeMaterialManager
  public static tdsLoader: ThreeTDSLoader
  public static gltfLoader: ThreeGLTFLoader

  //#endregion three-render

  //#region resource-management 资源管理
  public static threeModelResourceManager: ThreeModelResourceManager
  public static zipLoader: RoomZIPLoader

  //#endregion resource-management

  private constructor() {}

  public static initGlobalForThree() {
    this.doServiceContainer = new DomainServiceContainer()

    this.initGlobalResourceManagement()

    //#region three-render three渲染
    this.threeSceneController = new ThreeSceneController()
    this.threeRender3DController = new ThreeRender3DController()
    this.meshBuilderManager = MeshBuilderManager.getInstance()
    this.threeTextureManager = ThreeTextureManager.getInstance()
    this.threeMaterialManager = ThreeMaterialManager.getInstance()
    this.tdsLoader = new ThreeTDSLoader()
    this.gltfLoader = new ThreeGLTFLoader()
    this.threeModelResourceManager = new ThreeModelResourceManager()

    //#endregion three-render
  }

  private static initGlobalResourceManagement() {
    this.zipLoader = new RoomZIPLoader()
  }
}
